package jsu.blogger.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class FileUtil {
    private static final Logger logger = LoggerFactory.getLogger(FileUtil.class);
   public static final List<String> BASE_PATH = Arrays.asList(
            "src",
            "main",
            "resources",
            "static",
            "img"
    );

    public static final String POST_COVER_DIR_NAME="postCover";
    public static final String PROFILE_PICTURE_DIR_NAME="profilePicture";
    public static final String POST_IMG_DIR_NAME="postImg";
    public static final String TEMP_POST_IMG_DIR_NAME="tempPostImg";
    public static final String TEMP_POST_COVER_DIR_NAME="tempPostCover";

    //C:\Users\徐海东\Desktop\javapro\blogger\src\main\resources\static\img
    public static final String resourcePath = System.getProperty("user.dir") + File.separator + toRelativePath(BASE_PATH);

    // 将 List<String> 转换为相对路径
    public static String toRelativePath(List<String> pathParts) {
        StringBuilder relativePath = new StringBuilder();
        String separator = File.separator; // 获取当前平台的路径分隔符
        for (String part : pathParts) {
            relativePath.append(part).append(separator);
        }
        // 删除最后一个多余的分隔符
        if (relativePath.length() > 0) {
            relativePath.setLength(relativePath.length() - separator.length());
        }
        return relativePath.toString();
    }

    public static String  createDirPath(String signDir){
        return   resourcePath + File.separator + signDir;
    }

    public static  boolean createDirBySignId(String signDir,String signId){
        // 拼接完整的目录路径
        String dirPath = resourcePath + File.separator + signDir + File.separator + signId;
        logger.info("需要创建的路径是: " + dirPath);
        File directory = new File(dirPath);
        // 判断目录是否存在
        if (!directory.exists()) {
            // 尝试创建目录
            return directory.mkdirs(); // 使用 mkdirs() 方法可以创建多层目录
        } else {
            return true; // 返回 true 表示目录已存在
        }
    }
    public static  boolean createDirByPath(String dirPath){
        // 拼接完整的目录路径
        logger.info("完整路径是: " + dirPath);
        File directory = new File(dirPath);
        // 判断目录是否存在
        if (!directory.exists()) {
            // 尝试创建目录
            return directory.mkdirs(); // 使用 mkdirs() 方法可以创建多层目录
        } else {
            return true; // 返回 true 表示目录已存在
        }
    }


    //图片是否存在   signPath由 类型名字 和 标识
    public static String isImageExists(String signDir,String signId) {
        String dirPath = resourcePath + File.separator +signDir;
        if (!createDirByPath(dirPath)){
            return null;
        }
        // 定义支持的图片格式
        String[] supportedFormats = {".jpg", ".jpeg", ".png", ".gif", ".bmp", ".svg"};
        // 遍历每种格式，检查文件是否存在
        for (String format : supportedFormats) {
            String imagePath = dirPath+File.separator+signId+format;

            File imageFile = new File(imagePath); // 创建 File 对象

            try {
                // 检查资源是否存在并且是文件
                if (imageFile.exists() && imageFile.isFile()) {
                    return imagePath; // 找到文件，返回其绝对路径
                }
            } catch (Exception e) {
                // 处理异常，记录日志
                e.printStackTrace();
                // 继续检查下一个格式
            }
        }
        return null; // 所有格式检查完毕，返回 false
    }
    public static File getFile(String signDir, String signId) {
        // 使用 isImageExists 方法检查文件是否存在
        String imagePath = isImageExists(signDir, signId);

        // 如果文件存在，构建完整路径并返回 File 对象
        if (imagePath != null) {
            // 创建并返回对应的 File 对象
            File imgFile = new File(imagePath);
            if (imgFile.exists() && imgFile.isFile()) {
                return imgFile;
            }
        }

        // 如果文件不存在或发生异常，返回 null
        return null;
    }

    public static Map<String, Object> getImgAsBase64ByPath(String resourcePath) {
        Map<String, Object> reMap = new HashMap<>();
        try {
            File imgFile = new File(resourcePath);
            // 将文件内容读取为字节数组
            byte[] fileContent = Files.readAllBytes(imgFile.toPath());
            // 将字节数组编码为 Base64 字符串
            String base64String = Base64.getEncoder().encodeToString(fileContent);
            // 假设 imgType 是文件类型，你可以根据需要设置
            String imgType = getImageType(imgFile); // 需要实现这个方法以获取文件类型
            reMap.put("imgType", imgType);
            // 获取文件名
            String fileName = imgFile.getName();
            reMap.put("fileName", fileName);
            reMap.put("fileContent", base64String);
        } catch (IOException e) {
            logger.info("img报错" + e.getMessage());
            reMap.put("error", "Image not found");
        }
        return reMap; // 返回包含 Base64 字符串的 Map 对象
    }

    public static Map<String, Object> getImgAsBase64(String signDir, String signId) {
        File imgFile = getFile(signDir,signId);
        Map<String, Object> reMap = new HashMap<>();
        if (imgFile != null) {
            try {
                // 将文件内容读取为字节数组
                byte[] fileContent = Files.readAllBytes(imgFile.toPath());
                // 将字节数组编码为 Base64 字符串
                String base64String = Base64.getEncoder().encodeToString(fileContent);
                // 假设 imgType 是文件类型，你可以根据需要设置
                String imgType = getImageType(imgFile); // 需要实现这个方法以获取文件类型
                reMap.put("imgType", imgType);
                // 获取文件名
                String fileName = imgFile.getName();
                reMap.put("fileName", fileName);
                reMap.put("fileContent", base64String);
            } catch (IOException e) {
                logger.info("img报错"+e.getMessage());
                reMap.put("error", "Image not found");
            }
        } else {
            reMap.put("error", "Image not found");
        }

        return reMap; // 返回包含 Base64 字符串的 Map 对象
    }

    // 获取指定目录中按文件名数字排序的最大文件
    public static File getMaxValueFileInDirectory(String dirPath) {
        File directory = new File(dirPath);

        // 检查目录是否存在且是一个文件夹
        if (directory.exists() && directory.isDirectory()) {
            // 获取文件夹中的所有文件，过滤掉目录，保留文件
            File[] files = directory.listFiles(file -> file.isFile());

            if (files != null && files.length > 0) {
                // 过滤掉没有纯数字文件名的文件，按文件名中的数字排序，返回最大值文件
                return Arrays.stream(files)
                        .filter(file -> {
                            // 提取文件名中的数字部分，去掉扩展名
                            String fileName = file.getName();
                            String numberPart = extractNumber(fileName);
                            return numberPart != null;  // 确保文件名是纯数字
                        })
                        .max(Comparator.comparingInt(file -> {
                            // 提取文件名中的数字部分
                            String fileName = file.getName();
                            String numberPart = extractNumber(fileName);
                            return Integer.parseInt(numberPart);  // 返回数字进行比较
                        }))
                        .orElse(null); // 如果没有符合条件的文件，返回 null
            } else {
                logger.error("目录中没有文件或所有文件都不是纯数字命名");
                return null;
            }
        } else {
            logger.error("指定的路径不存在或者不是一个有效的文件夹: {}", dirPath);
            return null;
        }
    }

    // 提取文件名中的数字部分，去掉扩展名，要求文件名只能是纯数字
    public static String extractNumber(String fileName) {
        // 去掉文件扩展名部分，取文件名的前半部分
        int dotIndex = fileName.lastIndexOf(".");
        if (dotIndex != -1) {
            fileName = fileName.substring(0, dotIndex);  // 去掉扩展名
        }

        // 检查文件名是否完全由数字组成
        if (fileName.matches("\\d+")) {
            return fileName;  // 返回文件名中的数字部分
        } else {
            return null;  // 如果文件名不是纯数字，返回 null
        }
    }
    // 辅助方法，获取文件类型
   public  static String getImageType(File file) {
        String fileName = file.getName();
       int dotIndex = fileName.lastIndexOf('.');
       if (dotIndex == -1) {
           return "";  // 或者返回 "unknown" 或者自定义的值
       }
        return fileName.substring(dotIndex + 1); // 获取文件扩展名
    }

    // 删除指定目录中包含部分文件名的文件
    public static void deleteFilesByPartialName(String storagePath, String partialFileName) {
        File directory = new File(storagePath);

        if (!directory.exists() || !directory.isDirectory()) {
            logger.error("指定的路径无效或不是目录: " + storagePath);
            return;
        }

        // 获取目录中的所有文件
        File[] files = directory.listFiles((dir, name) -> name.contains(partialFileName));

        if (files == null || files.length == 0) {
            logger.error("没有找到符合条件的文件.");
            return;
        }

        // 遍历并删除匹配的文件
        for (File file : files) {
            if (file.exists() && file.isFile()) {
                boolean deleted = file.delete();
                if (deleted) {
                    logger.info("已删除文件: " + file.getName());
                } else {
                    logger.error("删除失败: " + file.getName());
                }
            }
        }
    }
    //将某个地址的文件 复制到另一个地址并重命名

    public static boolean copyFileAndRename(Path sourcePath, Path targetDir, String newFileName) {
        // 检查源文件是否存在
        if (Files.notExists(sourcePath)) {
            return false;  // 源文件不存在，返回 false
        }
        // 创建目标目录，如果目标目录不存在
        if (Files.notExists(targetDir)) {
            try {
                Files.createDirectories(targetDir);  // 创建目录及其父目录
                logger.info("目标目录已创建: " + targetDir);
            } catch (IOException e) {
                e.printStackTrace();
                logger.error("创建目标目录时出错！");
                return false;  // 创建目录失败，返回 false
            }
        }
        // 组合目标文件的完整路径
        Path targetPath = targetDir.resolve(newFileName);
        try {
            // 复制文件到目标路径并重命名，如果目标文件已存在则覆盖
            Files.copy(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
            logger.info("文件已成功复制并重命名！");
            return true;  // 文件复制成功
        } catch (IOException e) {
            e.printStackTrace();
            logger.error("复制文件时出错！");
            return false;  // 发生异常，返回 false
        }
    }

    //修改所有FileName
    public static String replaceStorageFileName(String htmlContent, String oldFileName, String newFileName) {
        // 创建正则表达式模式，用于匹配 storageFileName=oldFileName
        String regex = "storageFileName=" + Pattern.quote(oldFileName);
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(htmlContent);
        // 替换匹配的字符串
        return matcher.replaceAll("storageFileName=" + newFileName);
    }

    // 获取需要删除的文件列表
    public static List<File> getFilesToDelete(String dirPath,Set<String> filesToKeep) {
        List<File> filesToDelete = new ArrayList<>();
        File dir = new File(dirPath);
        if (dir.exists() && dir.isDirectory()) {
            File[] allFiles = dir.listFiles();
            if (allFiles != null) {
                for (File file : allFiles) {
                    // 判断文件名是否在不需要删除的文件列表中
                    if (!filesToKeep.contains(file.getName())) {
                        filesToDelete.add(file);
                    }
                }
            }
        }
        return filesToDelete;
    }

    public static boolean deleteDirectory(File dir) {
        // 确保目录存在且是一个目录
        if (dir.exists() && dir.isDirectory()) {
            // 获取目录中的所有文件和子目录
            File[] files = dir.listFiles();
            if (files != null) {
                for (File file : files) {
                    // 如果是子目录，递归删除
                    if (file.isDirectory()) {
                        deleteDirectory(file);
                    } else {
                        // 如果是文件，直接删除
                        file.delete();
                    }
                }
            }
            // 删除空目录
            return dir.delete();
        } else {
            // 如果传入的路径不是一个目录
           logger.info("目录删除失败: " + dir.getAbsolutePath());
            return false;
        }
    }

    // 查找不指定后缀名的文件
    public static List<File> findFilesByNameWithoutExtension(File dir, String fileNameWithoutExtension) {
        List<File> matchingFiles = new ArrayList<>();

        // 检查目录是否存在且是一个目录
        if (dir.exists() && dir.isDirectory()) {
            // 获取目录中的所有文件
            File[] files = dir.listFiles();
            if (files != null) {
                for (File file : files) {
                    // 如果是文件且文件名去除后缀后匹配
                    if (file.isFile()) {
                        String fileName = file.getName();
                        // 获取文件名（去掉扩展名）
                        String baseName = fileName.substring(0, fileName.lastIndexOf("."));
                        // 比较去除扩展名后的文件名
                        if (baseName.equals(fileNameWithoutExtension)) {
                            matchingFiles.add(file);
                        }
                    }
                }
            }
        }
        return matchingFiles;
    }
}
